﻿﻿﻿using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using SubNPhoenix.Resources;
using System;
using System.Diagnostics;
using System.Threading.Tasks;

namespace SubNPhoenix
{
    public class MainWindowViewModel : ObservableObject
    {
        private string token;
        private int port;
        private int pid;
        private GameConnector _gameConnector;
        private readonly string _cmdPath = @"C:\Windows\System32\cmd.exe";
        private readonly string _excuteShell = "wmic PROCESS WHERE name='LeagueClientUx.exe' GET commandline";
        public const string GameFlowChannel = @"/lol-gameflow/v1/gameflow-phase";
        
        private readonly Random _random = new Random();

        /// <summary>
        /// 是否自动接收对局
        /// </summary>
        private bool _autoAcceptGame;
        public bool AutoAcceptGame
        {
            get => _autoAcceptGame;
            set
            {
                if (SetProperty(ref _autoAcceptGame, value))
                {
                    _ = Task.Run(async () => await IniSettingsModel.Instance.WriteAutoAcceptGameAsync(value));
                }
            }
        }

        /// <summary>
        /// 游戏状态
        /// </summary>
        private string _gameStatus = "初始化中...";
        public string GameStatus
        {
            get => _gameStatus;
            set => SetProperty(ref _gameStatus, value);
        }
        
        /// <summary>
        /// 底部状态指示
        /// </summary>
        private string _bottomStatus = "启动中";
        public string BottomStatus
        {
            get => _bottomStatus;
            set => SetProperty(ref _bottomStatus, value);
        }
        
        public AsyncRelayCommand LoadCommandAsync { get; set; }
        public RelayCommand<string> OpenUrlCommand { get; set; }
        
        private string _lastGameStatus = string.Empty; // 状态缓存，避免重复更新
        
        public MainWindowViewModel()
        {
            LoadCommandAsync = new AsyncRelayCommand(LoadAsync);
            OpenUrlCommand = new RelayCommand<string>(OpenUrl);
        }

        private void OpenUrl(string url)
        {
            try
            {
                System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo(url) { UseShellExecute = true });
            }
            catch (System.Exception ex)
            {
                // 记录错误或显示错误消息
                System.Windows.MessageBox.Show($"无法打开链接: {ex.Message}", "错误", System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Warning);
            }
        }

        private async Task LoadAsync()
        {
            try
            {
                GameStatus = "正在初始化...";
                BottomStatus = "启动中";
                
                await IniSettingsModel.Instance.InitializeAsync();
                AutoAcceptGame = IniSettingsModel.Instance.AutoAcceptGame;
                
                GameStatus = "正在连接游戏...";
                await ConnnectAsync();
                
                GameStatus = "已连接上游戏";
                BottomStatus = "运行中";
                _gameConnector.Subscribe(GameFlowChannel, new EventHandler<EventArgument>(GameFlow));

                await LoopforClientStatus();
            }
            catch (Exception ex)
            {
                GameStatus = "初始化失败";
                BottomStatus = "错误";
                System.Windows.MessageBox.Show($"应用程序初始化失败: {ex.Message}", "错误", 
                    System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Error);
            }
        }

        /// <summary>
        /// 游戏状态变化处理
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="event">数据</param>
        private async void GameFlow(object obj, EventArgument @event)
        {
            var data = $"{@event.Data}";
            if (string.IsNullOrEmpty(data) || data == _lastGameStatus)
                return; // 避免重复更新相同状态

            _lastGameStatus = data;

            await System.Windows.Application.Current.Dispatcher.InvokeAsync(async () =>
            {
                string newStatus = data switch
                {
                    "ReadyCheck" => "找到对局",
                    "None" => "大厅中",
                    "Reconnect" => "等待重连",
                    "Lobby" => "房间中",
                    "Matchmaking" => "匹配中",
                    "InProgress" => "游戏中",
                    "GameStart" => "游戏开始",
                    "WaitingForStats" => "等待结算",
                    "PreEndOfGame" => GameStatus, // 保持当前状态
                    "EndOfGame" => "对局结束",
                    _ => $"未知状态: {data}"
                };

                // 只在状态真正改变时更新UI
                if (GameStatus != newStatus)
                {
                    GameStatus = newStatus;
                }

                // 处理自动接收逻辑
                if (data == "ReadyCheck" && AutoAcceptGame)
                {
                    try
                    {
                        // 添加1-2秒的随机延迟
                        var delayMs = _random.Next(1000, 2001);
                        await Task.Delay(delayMs);
                        await _gameConnector.AutoAcceptGameAsync();
                        GameStatus = "已自动接受对局";
                    }
                    catch (Exception ex)
                    {
                        GameStatus = "自动接受失败";
                        // 可以选择记录错误日志
                    }
                }
            });
        }

        #region 连接客户端
        private async Task ConnnectAsync()
        {
            while (true)
            {
                try
                {
                    var authenticate = await GetAuthenticate();
                    if (!string.IsNullOrEmpty(authenticate) && authenticate.Contains("--remoting-auth-token="))
                    {
                        var tokenResults = authenticate.Split("--remoting-auth-token=");
                        var portResults = authenticate.Split("--app-port=");
                        var PidResults = authenticate.Split("--app-pid=");
                        var installLocations = authenticate.Split("--install-directory=");
                        token = tokenResults[1].Substring(0, tokenResults[1].IndexOf("\""));
                        port = int.TryParse(portResults[1].Substring(0, portResults[1].IndexOf("\"")), out var temp) ? temp : 0;
                        pid = int.TryParse(PidResults[1].Substring(0, PidResults[1].IndexOf("\"")), out var temp1) ? temp1 : 0;
                        if (string.IsNullOrEmpty(token) || port == 0)
                            throw new InvalidOperationException("invalid data when try to crack.");

                        _gameConnector = new GameConnector(port, token);
                        await _gameConnector.ConnectAsync();

                        break;
                    }
                    else
                        throw new InvalidOperationException("can't read right token and port");
                }
                catch (Exception ex)
                {
                    await Task.Delay(2000);
                }
            }
        }

        /// <summary>
        /// 获取控制台的lol的相关参数
        /// </summary>
        /// <returns>lol的相关参数</returns>
        private async Task<string> GetAuthenticate()
        {
            using (Process p = new Process())
            {
                p.StartInfo.FileName = _cmdPath;
                p.StartInfo.UseShellExecute = false; //是否使用操作系统shell启动
                p.StartInfo.RedirectStandardInput = true; //接受来自调用程序的输入信息
                p.StartInfo.RedirectStandardOutput = true; //由调用程序获取输出信息
                p.StartInfo.RedirectStandardError = true; //重定向标准错误输出
                p.StartInfo.CreateNoWindow = true; //不显示程序窗口
                p.Start();
                p.StandardInput.WriteLine(_excuteShell.TrimEnd('&') + "&exit");
                p.StandardInput.AutoFlush = true;
                string output = await p.StandardOutput.ReadToEndAsync();
                p.WaitForExit();
                p.Close();

                return output;
            }
        }
        #endregion

        #region 循环感知客户端是否在线
        private bool _isLoop = false;
        private async Task LoopforClientStatus()
        {
            if (_isLoop)
                return;

            _isLoop = true;
            await Task.Yield();
            
            while (true)
            {
                try
                {
                    var data = await _gameConnector.FetchCurrentAccountInfoAsync();
                    if (data == null)
                        throw new Exception("未知的登录信息");

                    // 确保底部状态显示为运行中
                    if (BottomStatus != "运行中")
                    {
                        System.Windows.Application.Current.Dispatcher.Invoke(() =>
                        {
                            BottomStatus = "运行中";
                        });
                    }

                    await Task.Delay(5000); // 增加检查间隔，减少CPU占用
                }
                catch (Exception ex)
                {
                    System.Windows.Application.Current.Dispatcher.Invoke(() =>
                    {
                        GameStatus = "连接断开";
                        BottomStatus = "重连中";
                    });

                    // 尝试重新连接
                    try
                    {
                        await ConnnectAsync();
                        System.Windows.Application.Current.Dispatcher.Invoke(() =>
                        {
                            GameStatus = "重新连接成功";
                            BottomStatus = "运行中";
                        });
                        _gameConnector.Subscribe(GameFlowChannel, new EventHandler<EventArgument>(GameFlow));
                    }
                    catch
                    {
                        System.Windows.Application.Current.Dispatcher.Invoke(() =>
                        {
                            GameStatus = "重连失败";
                            BottomStatus = "错误";
                        });
                    }

                    await Task.Delay(5000); // 重连失败后等待更长时间
                }
            }
        }
        #endregion
    }
}
